oo::class create Pair {
    superclass Plugin
    variable TextWidget Pair PairKeySym Language Tag

    constructor {textWidget pair pairKeySym color tagName} {
        set TextWidget $textWidget
        set Pair $pair
        set PairKeySym $pairKeySym
        set Language [uplevel set Language]
        set Tag $tagName

        set originWidget [string trimleft $textWidget _]
        # use originWidget to keep the effect of other plugins
        bind $originWidget  <[lindex $PairKeySym 0]> "+
            after idle {
                $originWidget insert insert \\[lindex $Pair 1]
                $originWidget mark set insert \[$textWidget index insert\]-1c
            }
        "

        # set boldFont [concat [font configure [lindex [$textWidget configure -font] end]] -weight bold]
        set boldFont [my CreateBoldFont $TextWidget]
        $TextWidget tag configure $Tag -background $color -font $boldFont
        $TextWidget tag raise $Tag
    }

    method CreateBoldFont {widget} {
        set font [lindex [$widget configure -font] end]
        set family [lindex $font 0]
        set size [lindex $font 1]
        set rest [lreplace $font 0 1]
        set i 0
        foreach e $rest {
            if {$e == "normal" || $e == "bold"} {
                return [list $family $size {*}[lreplace $rest $i $i bold]]
            }
            incr i
        }
        return [list $family $size {*}$rest bold]
    }

    method hilightPair {args} {
        $TextWidget tag remove $Tag 1.0 end

        set id [$TextWidget index insert]
        foreach {h t} $Pair {}
        set c [$TextWidget get $id]
        if {$c == $h} {
            $TextWidget tag add $Tag $id
            if ![catch {$Language getPairEnd $TextWidget $id+1c $Pair} eid] {
                $TextWidget tag add $Tag $eid
            }
        } elseif {$c == $t} {
            $TextWidget tag add $Tag $id
            if ![catch {$Language getPairHead $TextWidget $id $Pair} hid] {
                $TextWidget tag add $Tag $hid
            }
            # puts $::errorInfo
        }
    }

    method getPluginEvents {} {
        return {
            {afterSee hilightPair}
        }
    }
}